/*
 * Copyright 2011-2012 by The Regents of the University of California Licensed
 * under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. you may obtain a copy of the
 * License from
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package edu.ucsd.db.bassarisk.storage.reading;

import edu.ucsd.db.bassarisk.data.api.IValueType;
import edu.ucsd.db.bassarisk.data.api.IValueType.IValueReference;

/**
 * A common interface for classes that read values from Bassarisk column store
 * columns, and/or smaller segments of such columns.
 * 
 * The reader interface is part cursor, part iterator. Values are read in a
 * forward-only manner. Readers are optimized for access that jumps forward
 * skipping many entries in a forward only manner.
 * 
 * @author nbales
 */
public interface IColumnSegmentReader<VT extends IValueType> {
  void close();

  /**
   * Test a column part to see if a desired column entry, identified by index
   * with respect to the column, is contained within the part as opposed to
   * another part of the same column.
   * 
   * @param targetEntryIndex
   *          An index of a column index that may be in this column part.
   * @return True if the value associated with <code>targetEntryIndex</code> can
   *         be found in this column part. False if the value assocaited with
   *         <code>targtEntryIndex</code
   */
  boolean hasEntryIndex(long targetEntryIndex);
  
  /**
   * Test a column part to see if a desired value is within the value range
   * covered by this column part.
   * 
   * Requires that the part belongs to a sorted column.
   * 
   * @param targetValue
   *          A value to compare against the range of this column part.
   * @return True if <code>targetValue</code> is between the maximum value of this
   *         column part and the minimum value of this column part inclusive.
   */
  boolean hasValue(IValueReference<VT> targetValue);

  boolean isInitialized();

  /**
   * Jump the reader to the entry at index, with respect to the column, of
   * <code>targetEntryIndex</code>. And write that entry to
   * <code>valueOut</code>.
   * 
   * It is an error if the entry with index <code>targetEntryIdx</code> is not
   * in this part of the column.
   * 
   * @param targetEntryIdx
   *          The index, with respect to the column, which to jump to.
   * @param valueOutput
   *          The value of the entry at index <code>columnIndex</code> is
   *          written to this output stream.
   */
  void jumpCursor(int targetEntryIndex, IValueReference<VT> valueOutput);

  /**
   * Jump the reader to the first entry with a value equal or greater than
   * <code>minimumTargetValue</code>. And write that entry to
   * <code>valueOut</code>.
   * 
   * It is an error to call this method on a column that is not sorted.
   * 
   * It is an error to call this method if no value in this column part is
   * greater than or equal to <code>minimumTargetValue</code>.
   * 
   * @param minimumTargetValue
   *          A target value for the reader advance. The reader will be advanced
   *          to the first value in the column greater-than-or-equal-to this
   *          value.
   * @param valueOut
   *          The value of the first entry greater-than or equal-to
   *          <code>postingStart</code> is written to this value reference.
   * @return Returns true when a minimum value is found on this card. Returns
   *         false when no value on this card has at least the minimum value.
   *         When returning false, the value of <code>valueOut</code> is
   *         unspecified.
   */
  boolean jumpCursorToValue(IValueReference<VT> minimumTargetValue,
                            IValueReference<VT> valueOut);

  /**
   * Step the reader forward one value. And write the next entry to
   * <code>postingOut</code>.
   * 
   * It is an error to call this method if the reader is already on the last
   * entry in this part.
   * 
   * @param valueOut
   *          The value of the next entry is written to this value reference.
   * @return Returns true if there is an entry in this column part to step onto.
   *         When there is no such entry, returns false and
   *         <code>postingOut</code> is not populated.
   */
  boolean stepCursor(IValueReference<VT> valueOut);
}
